feat(dns): manage Scriptable DNS scripts with ambient runtime types#104
feat(dns): manage Scriptable DNS scripts with ambient runtime types#104jamie-at-bunny wants to merge 4 commits into
Conversation
🦋 Changeset detectedLatest commit: 6464333 The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@codex review |
Greptile SummaryThis PR adds Scriptable DNS management to the CLI. The main changes are:
Confidence Score: 4/5This is close, but I would fix the type declaration before merging.
packages/scriptable-dns-types/index.d.ts Important Files Changed
Reviews (3): Last reviewed commit: "static-vs-scriptable" | Re-trigger Greptile |
| action: string, | ||
| interactive: boolean, | ||
| ): Promise<number> { | ||
| if (id) return id; |
There was a problem hiding this comment.
When a non-numeric positional id is passed, yargs can provide NaN, and this truthiness check treats it as omitted. deploy or attach can then use the linked manifest or picker instead of rejecting the bad id, so a typo can target the wrong DNS script.
| if (id) return id; | |
| if (id !== undefined) { | |
| if (!Number.isFinite(id)) { | |
| throw new UserError("DNS script ID must be a number."); | |
| } | |
| return id; | |
| } |
Context Used: CLAUDE.md (source)
| const { data } = await client.GET("/compute/script", { | ||
| params: { query: { type: [SCRIPT_TYPE_DNS] } }, | ||
| }); |
There was a problem hiding this comment.
The compute script list endpoint is paginated, but this call only reads the first page. Accounts past the API page size will see incomplete dns scripts list output, and interactive deploy or attach pickers will omit valid DNS scripts unless the id is entered manually.
Context Used: CLAUDE.md (source)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9171b922fd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| file = value; | ||
| } | ||
| file ??= defaultFile; | ||
| const absPath = resolve(file); |
There was a problem hiding this comment.
Resolve default entry relative to the linked project
Because loadManifest() walks up to a parent .bunny/dns-script.json, a linked DNS script can be resolved while the process is in a subdirectory of the scaffolded project. The default entry stored by init is relative to that project root, but this resolves it against the current subdirectory, so bunny dns scripts deploy from src/ looks for src/handleQuery.js and fails with “File not found” even though the linked project has handleQuery.js at its root.
Useful? React with 👍 / 👎.
| type DnsAnswer = | ||
| | ARecord | ||
| | AaaaRecord | ||
| | CnameRecord | ||
| | TxtRecord | ||
| | PullZoneRecord | ||
| | Server; |
There was a problem hiding this comment.
Allow array responses in DnsAnswer
The Scriptable DNS docs allow returning an array of response objects, but this ambient DnsAnswer only permits a single object. Any user who annotates handleQuery with DnsAnswer and returns multiple A/CNAME/etc. records will fail the scaffolded tsc --noEmit check even though the script is valid at runtime; include array responses in this type.
Useful? React with 👍 / 👎.
| entry: DEFAULT_ENTRY, | ||
| }); | ||
| logger.success(`Created DNS script "${created.name}" (${created.id}).`); | ||
| } catch (err: unknown) { |
There was a problem hiding this comment.
Fail when explicit DNS script creation fails
When bunny dns scripts init ... --deploy is used by automation, this catch converts any config/API failure from creating the remote script into a warning and the command continues to emit successful JSON/exit 0 with no script. Callers that requested deployment will proceed without a remote script or manifest id, so explicit --deploy failures should be rethrown or returned as a nonzero JSON error while preserving the interactive warning path.
Useful? React with 👍 / 👎.
| const { data } = await client.GET("/compute/script", { | ||
| params: { query: { type: [SCRIPT_TYPE_DNS] } }, | ||
| }); |
There was a problem hiding this comment.
The compute list endpoint is paginated, but this helper only issues one GET with the DNS type filter. Accounts with more scripts than the first page will have dns scripts list, the attach picker, and the interactive SCRIPT-record picker silently omit valid scripts, so loop until HasMoreItems is false as the DNS zone helper does.
Useful? React with 👍 / 👎.
| action: string, | ||
| interactive: boolean, | ||
| ): Promise<number> { | ||
| if (id) return id; |
There was a problem hiding this comment.
Validate explicit DNS script IDs before deploying
When a user passes an explicit ID, this path returns it without checking that the target script is actually ScriptType: DNS. bunny dns scripts deploy handleQuery.js <id> can therefore upload and publish DNS handler code over an existing CDN or Middleware Edge Script if the wrong ID is supplied; fetch the script and reject non-DNS types before allowing deploy/attach operations to continue.
Useful? React with 👍 / 👎.
| if (!data) throw new UserError(`DNS script ${id} not found.`); | ||
| return data; |
There was a problem hiding this comment.
fetchDnsScript only checks that the compute script exists. dns scripts link <id> can therefore write a regular Edge Script id into .bunny/dns-script.json, and later dns scripts deploy will upload DNS code to that non-DNS script while dns scripts attach can create a SCRIPT record pointing at it. The helper should reject scripts whose ScriptType is not SCRIPT_TYPE_DNS before callers treat the id as a Scriptable DNS script.
| latitude?: number, | ||
| longitude?: number, | ||
| weight?: number, | ||
| online?: boolean, |
There was a problem hiding this comment.
The Server constructor accepts an online flag, and RoutingEngine has onlineOnly modes, but the instance type does not expose online. In a scaffolded project, checkJs: true means valid Scriptable DNS code such as filtering servers by server.online fails typecheck even though the runtime object was constructed with that state. Add the property so custom health-routing scripts can typecheck against the declared runtime shape.
No description provided.